package com.freemalll.merchant.common.convert;

import com.freemalll.common.core.exception.BusinessException;
import com.freemalll.merchant.domain.vo.merchantReport.MerchantBizPerfMonthConvertVo;
import com.freemalll.merchant.domain.vo.merchantReport.MerchantBizPerfMonthVo;
import com.freemalll.merchant.enums.BizFieldEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

public class MerchantReportDataConverter {

    private static final Logger log = LoggerFactory.getLogger(MerchantReportDataConverter.class);

    private static final List<String> COLUMN_ORDER = Arrays.asList(
            "申请笔数", "批核率", "放款笔数", "放款金额",
            "逾期笔数", "逾期金额", "首逾笔数", "逾期率",
            "首逾率", "新增逾期率"
    );

    public static List<MerchantBizPerfMonthConvertVo> convert(List<MerchantBizPerfMonthVo> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return Collections.emptyList();
        }

        // 结果容器
        List<MerchantBizPerfMonthConvertVo> result = new ArrayList<>();

        // 获取所有需要处理的字段
        List<String> fields = BizFieldEnum.getAllFields();

        // 分组：字段 → 年份 → 月份 → 值
        Map<String, Map<String, Map<Integer, String>>> groupedData = new HashMap<>();

        for (String field : fields) {
            groupedData.put(field, new HashMap<>());
        }

        // 遍历原始数据
        for (MerchantBizPerfMonthVo vo : dataList) {
            String[] parts = vo.getMonthId().split("-");
            String year = parts[0];
            int month = Integer.parseInt(parts[1]);

            for (String field : fields) {
                try {
                    Method method = vo.getClass().getMethod("get" + capitalize(field));
                    Object value = method.invoke(vo);
                    String strValue;
                    if (value instanceof BigDecimal) {
                        strValue = ((BigDecimal) value).setScale(8, RoundingMode.HALF_UP).toPlainString(); // 保留8位小数，防止精度丢失
                    } else {
                        strValue = value == null ? "" : value.toString();
                    }
                    groupedData.get(field)
                            .computeIfAbsent(year, k -> new HashMap<>())
                            .put(month, value == null ? "" : strValue);
                } catch (Exception e) {
                    log.error("数据转换异常:", e);
                    throw BusinessException.businessOther("数据转换异常");
                }
            }
        }

        // 构建 VO 列表
        for (Map.Entry<String, Map<String, Map<Integer, String>>> entry : groupedData.entrySet()) {
            String field = entry.getKey();
            String columnName = BizFieldEnum.getLabelByField(field);
            Map<String, Map<Integer, String>> yearMap = entry.getValue();

            for (Map.Entry<String, Map<Integer, String>> yearEntry : yearMap.entrySet()) {
                String yearId = yearEntry.getKey();
                Map<Integer, String> monthMap = yearEntry.getValue();

                MerchantBizPerfMonthConvertVo convertVo = new MerchantBizPerfMonthConvertVo();
                convertVo.setYearId(yearId);
                convertVo.setColumnName(columnName);

                for (int i = 1; i <= 12; i++) {
                    String value = monthMap.getOrDefault(i, "");
                    setMonthValue(convertVo, i, value);
                }

                result.add(convertVo);
            }
        }

        // 排序：先按 yearId 降序，再按指定列名顺序
        result.sort((v1, v2) -> {
            // Step 1: 按 yearId 降序排序
            int yearCompare = v2.getYearId().compareTo(v1.getYearId());
            if (yearCompare != 0) {
                return yearCompare;
            }

            // Step 2: 按指定列名顺序排序
            int index1 = COLUMN_ORDER.indexOf(v1.getColumnName());
            int index2 = COLUMN_ORDER.indexOf(v2.getColumnName());

            // 如果未找到列名，默认按原顺序（这里假设不可能发生）
            if (index1 == -1 || index2 == -1) {
                return 0;
            }

            return Integer.compare(index1, index2);
        });

        return result;
    }

    private static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    private static void setMonthValue(MerchantBizPerfMonthConvertVo vo, int month, String value) {
        switch (month) {
            case 1:
                vo.setMonth_1(value);
                break;
            case 2:
                vo.setMonth_2(value);
                break;
            case 3:
                vo.setMonth_3(value);
                break;
            case 4:
                vo.setMonth_4(value);
                break;
            case 5:
                vo.setMonth_5(value);
                break;
            case 6:
                vo.setMonth_6(value);
                break;
            case 7:
                vo.setMonth_7(value);
                break;
            case 8:
                vo.setMonth_8(value);
                break;
            case 9:
                vo.setMonth_9(value);
                break;
            case 10:
                vo.setMonth_10(value);
                break;
            case 11:
                vo.setMonth_11(value);
                break;
            case 12:
                vo.setMonth_12(value);
                break;
            default:
                break;
        }
    }
}
